using System;
using System.Collections.Generic;
using System.Reflection;

namespace ViScript.Core
{
    public class LanguageRuleFactory
    {
        private readonly ISentenceRuleFactory sentenceRuleFactory;

        public LanguageRuleFactory(ISentenceRuleFactory sentenceRuleFactory)
        {
            this.sentenceRuleFactory = sentenceRuleFactory;
        }

        protected LanguageRuleFactory()
        {
        }

        public virtual List<ISentenceRule> CreateSentenceRules(object obj, MethodInfo[] methods)
        {
            List<ISentenceRule> sentenceRules = new List<ISentenceRule>(methods.Length);
            foreach (MethodInfo method in methods)
            {
                sentenceRules.Add(sentenceRuleFactory.CreateSentenceRule(obj, method));
            }
            return sentenceRules;
        }

        public LanguageRule CreateLanguageRule(params object[] objs)
        {
            List<ISentenceRule> sentenceRules = new List<ISentenceRule>();
            foreach (object obj in objs)
            {
                sentenceRules.AddRange(CreateSentenceRules(obj, GetScriptableMethods(obj)));
            }
            return new LanguageRule(sentenceRules.ToArray());
        }

        public virtual MethodInfo[] GetScriptableMethods(object obj)
        {
            Type type = obj.GetType();
            MethodInfo[] methods = type.GetMethods();
            List<MethodInfo> scriptableMethos = new List<MethodInfo>();
            foreach (MethodInfo method in methods)
            {
                if (Attribute.IsDefined(method, typeof(ScriptableAttribute)))
                {
                    scriptableMethos.Add(method);
                }
            }
            return scriptableMethos.ToArray();
        }
    }
}